package com.tcc.assessment.logic;

import org.apache.commons.io.FileUtils;
import org.apache.xpath.operations.String;
import org.openqa.jetty.html.List;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;

import tcc.utils.None;

import com.tcc.assessment.AssessmentIdMapping;
import com.tcc.nav.logic.NavFinder;
import com.tcc.qa.test.util.ButtonFinder;
import com.tcc.qa.test.util.LinkFinder;
import com.tcc.qa.test.util.SelLogger;
import com.tcc.qa.test.util.SwitchTo;

public class Playback {

  public static void switchWindow(WebDriver webdriver) {
    SwitchTo.getWindowHandle(webdriver);
    SwitchTo.switchToIframe(webdriver, "myframe");
  }

  //This string is the Xpath of the page location. 
  static String pageXpath = "//div[@id='questionContainer']/form/div/table/tbody/tr[1]/td[3]";

  //This string is the Xpath of the title location.
  static String titleXpath = "//div[@id='questionContainer']/form/div/table/tbody/tr[1]/td[1]/h1";

  public static String getPageNavInfo(WebDriver webdriver) {
    return webdriver.findElement(By.xpath(pageXpath)).getText();
  }

  public static String getTitleInfo(WebDriver webdriver) {
    return webdriver.findElement(By.xpath(titleXpath)).getText();
  }

  /**
   * Short Answer
   */
  public static boolean isExistShortAnswerObj(WebDriver webdriver, int questionSeq) {
    return getShortAnswerObj(webdriver, questionSeq) != null;
  }

  public static WebElement getShortAnswerObj(WebDriver webdriver, int questionSeq) {
    WebElement questionDiv = webdriver.findElements(By.xpath("//td[@class='as_question']")).get(questionSeq - 1);
    String questionIndex = questionDiv.getAttribute("questionIndex");
    try {
      return webdriver.findElement(By.xpath("//textarea[@questionindex='" + questionIndex + "']"));//modify TEXTAREA to textarea, questionIndex to questionindex
    } catch (Throwable e) {
      System.out.println("Not Found Element QuestionIndex:" + questionIndex + " QuestionSeq:" + questionSeq);
      return null;
    }
  }

  public static String getShortAnswerValue(WebDriver webdriver, int questionSeq) {
    return getShortAnswerObj(webdriver, questionSeq).getAttribute("value");
  }

  /**
   * Essay
   */
  public static boolean isExistEssayObj(WebDriver webdriver, int questionSeq) {
    return getEssayObj(webdriver, questionSeq) != null;
  }

  public static WebElement getEssayObj(WebDriver driver, int questionSeq) {
    WebElement questionDiv = driver.findElements(By.xpath("//td[@class='as_question']")).get(questionSeq - 1);
    String questionIndex = questionDiv.getAttribute("questionIndex");
    try {
      return questionDiv.findElement(By.xpath(".//TEXTAREA[@questionindex='" + questionIndex + "']"));
    } catch (Throwable e) {
      return null;
    }
  }

  public static String getEssayValue(WebDriver webdriver, int questionSeq) {
    return getEssayObj(webdriver, questionSeq).getAttribute("value");
  }

  /**
   * FillInBlank
   */
  public static boolean isExistFillInBlankObj(WebDriver webdriver, int questionSeq) {
    return getFillInBlankObj(webdriver, questionSeq) != null;
  }

  public static WebElement getFillInBlankObj(WebDriver driver, int questionSeq) {
    WebElement questionDiv = driver.findElements(By.xpath("//td[@class='as_question']")).get(questionSeq - 1);
    String questionIndex = questionDiv.getAttribute("questionIndex");
    try {
      return questionDiv.findElement(By.xpath(".//input[@questionindex='" + questionIndex + "'  and (@type='text' or @type='TEXT')]"));
    } catch (Throwable e) {
      return null;
    }
  }

  public static String getFillInBlankValue(WebDriver webdriver, int questionSeq) {
    return getFillInBlankObj(webdriver, questionSeq).getAttribute("value");
  }

  /**
   * Choose One
   */
  public static boolean isExistChooseOneAsnwerObj(WebDriver webdriver, int questionSeq) {
    WebElement questionDiv = webdriver.findElements(By.xpath("//td[@class='as_question']")).get(questionSeq - 1);
    String questionIndex = questionDiv.getAttribute("questionIndex");
    List<WebElement> objs = questionDiv.findElements(By.xpath(".//input[@questionindex='" + questionIndex + "' and (@type='radio' or @type='RADIO')]"));
    return !None.isEmpty(objs);
  }

  public static WebElement getChooseOneAsnwerObj(WebDriver webdriver, int questionSeq, int answerSeq) {
    WebElement questionDiv = webdriver.findElements(By.xpath("//td[@class='as_question']")).get(questionSeq - 1);
    String questionIndex = questionDiv.getAttribute("questionIndex");
    try {
      return questionDiv.findElements(By.xpath(".//input[@questionindex='" + questionIndex + "' and (@type='radio' or @type='RADIO')]")).get(answerSeq - 1);
    } catch (Throwable e) {
      return null;
    }
  }

  /**
   * Matching One
   */
  public static boolean isExistMatchingOneObj(WebDriver webdriver, int questionSeq) {
    WebElement questionDiv = webdriver.findElements(By.xpath("//td[@class='as_question']")).get(questionSeq - 1);
    String questionIndex = questionDiv.getAttribute("questionIndex");
    List<WebElement> objs = questionDiv.findElements(By.xpath(".//input[@questionindex='" + questionIndex + "' and (@type='text' or @type='TEXT')]"));
    return !None.isEmpty(objs);
  }

  public static WebElement getMatchingOneObj(WebDriver webdriver, int questionSeq, int answerSeq) {
    WebElement questionDiv = webdriver.findElements(By.xpath("//td[@class='as_question']")).get(questionSeq - 1);
    String questionIndex = questionDiv.getAttribute("questionIndex");
    try {
      return questionDiv.findElements(By.xpath(".//input[@questionindex='" + questionIndex + "' and (@type='text' or @type='TEXT')]")).get(answerSeq - 1);
    } catch (Throwable e) {
      return null;
    }
  }

  public static String getMatchingOneValue(WebDriver webdriver, int questionSeq, int answerSeq) {
    return getMatchingOneObj(webdriver, questionSeq, answerSeq).getAttribute("value");
  }

  /**
   * initPlaybakcer
   */
  private static final SelLogger logger = SelLogger.getLogger(Playback.class);
  public static WebDriver initPlaybacker(WebDriver webdriver, String AssessmentName) throws InterruptedException {
    webdriver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
    logger.pass("initPlaybacker");
    Thread.sleep(3000);
    NavFinder.gotoTabPage(webdriver, "Academics");
    Thread.sleep(3000);
    LinkFinder.getLinkByText(webdriver, AssessmentIdMapping.Test_CLassNAME).click();
    Thread.sleep(3000);
    NavFinder.gotoMenuOptionPage(webdriver, "My Assessments");
    webdriver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
    Thread.sleep(3000);
    String assessmentId = AssessmentIdMapping.getId(AssessmentName);
    ButtonFinder.getLinkButton(webdriver, "New Attempt", "href", assessmentId).click();
    Thread.sleep(7000);
    Playback.switchWindow(webdriver);
    Thread.sleep(7000);
    ButtonFinder.getInputButtonByValue(webdriver, "Start Session").click();
    return webdriver;
  }

  /**
   * resumePlaybacker
   */

  public static void resumePlaybacker(WebDriver webdriver, String AssessmentName) throws InterruptedException {
    webdriver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
    String assessmentId = AssessmentIdMapping.getId(AssessmentName);
    ButtonFinder.getLinkButton(webdriver, "Resume", "href", assessmentId).click();
    Thread.sleep(7000);
    Playback.switchWindow(webdriver);
    Thread.sleep(7000);
    ButtonFinder.getInputButtonByValue(webdriver, "Start Session").click();
  }

  /**
   * abortPlaybacker
   */

  public static void abortPlaybacker(WebDriver webdriver) throws InterruptedException {
    webdriver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
    SwitchTo.switchToDefault(webdriver);
    ButtonFinder.getTableButton(webdriver, "Close").click();
    Playback.switchWindow(webdriver);
    webdriver.findElement(By.xpath("//*[@id='asClose']/table/tbody/tr[2]/td/input[1]")).click();// click "Yes"
    Playback.switchWindow(webdriver);
    WebElement btn = ButtonFinder.getInputByValue(webdriver, "Close");
    String hds = SwitchTo.getWindowHandle(webdriver, 0);
    btn.click();
    Thread.sleep(3000);
    SwitchTo.getWindowHandle(webdriver, hds);
    Thread.sleep(3000);
  }

  /**
   * finishPlaybacker
   */

  public static void finishPlaybacker(WebDriver webdriver) throws InterruptedException {
    webdriver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
    ButtonFinder.getTableButton(webdriver, "Finish").click();
    Playback.switchWindow(webdriver);
    webdriver.findElement(By.xpath("//*[@id='asFinish']/table/tbody/tr[2]/td/input[1]")).click();// click "Yes"                                                                                       
  }

  public static void closePlaybacker(WebDriver webdriver) throws InterruptedException {
    webdriver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
    switchWindow(webdriver);
    String hds = SwitchTo.getWindowHandle(webdriver,0);
    ButtonFinder.getInputByValue(webdriver, "Close").click();
    SwitchTo.getWindowHandle(webdriver,hds);
  }

  public static void finishAndClosePlaybacker(WebDriver webdriver) throws InterruptedException {
    finishPlaybacker(webdriver);
    closePlaybacker(webdriver);
  }

  public static void toResume(WebDriver webdriver, String AssessmentName) throws InterruptedException {
    switchWindow(webdriver);
    WebElement btn = ButtonFinder.getInputByValue(webdriver, "Close");
    ButtonFinder.getTableButton(webdriver, "Close");
    String hds = SwitchTo.getWindowHandle(webdriver, 0);
    btn.click();
    Thread.sleep(3000);
    SwitchTo.getWindowHandle(webdriver, hds);
    Thread.sleep(3000);
    String assessmentId = AssessmentIdMapping.getId(AssessmentName);
    ButtonFinder.getLinkButton(webdriver, "Resume", "href", assessmentId).click();
    SwitchTo.getWindowHandle(webdriver);
    SwitchTo.switchToIframe(webdriver, "myframe");
    Thread.sleep(3000);
    ButtonFinder.getInputButtonByValue(webdriver, "Start Session").click();
  }

  /**
   * Previous & Next 
   */

  public static void goPrePlaybackPage(WebDriver webdriver) throws InterruptedException {
    Thread.sleep(3000);
    ButtonFinder.getTableButton(webdriver, "Previous").click();
  }

  public static void goNextPlaybackPage(WebDriver webdriver) throws InterruptedException {
    Thread.sleep(3000);
    ButtonFinder.getTableButton(webdriver, "Next").click();
  }

  /**
   * @Take Screen Shot action to verify question contains picture
   */
  private static WebDriver screenShot(WebDriver driver, String screenshotName) {
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss SS");
    Calendar ca = Calendar.getInstance();
    try {
      File screenshotFile = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
      FileUtils.copyFile(screenshotFile, new File("logs//TestReport//TestImg//" + screenshotName + sdf.format(ca.getTime()) + ".png"));
    } catch (Exception e) {
      e.printStackTrace();
    }
    return driver;
  }

  /**
   * @Check Navigation Map Color
   */

  public static int checkNavMapColor(WebDriver driver, SelLogger logger, int fromPage, int toPage, String expectColor) {
    int errorCount = 0;
    String colorStyle = null;
    if (expectColor == "Grey") {
      colorStyle = "background-color: rgb(221, 221, 221)";
    } else if (expectColor == "White") {
      colorStyle = "background-color:";
    } else if (expectColor == "Green") {
      colorStyle = "background-color: rgb(153, 255, 153)";
    } else if (expectColor == "Red") {
      colorStyle = "background-color: rgb(255, 153, 153)";
    }
    List<String> color = new ArrayList<String>();
    List<WebElement> weList = driver.findElements(By.xpath("//*[@id='assessmentContentNav']//td[@class='ccOutline' and count(a) > 0]"));
    for (int i = 0; i < weList.size(); i++) {
      color.add(driver.findElement(By.xpath("//table[@id='assessmentContentNav']/tbody/tr[" + (i / 5 + 1) + "]/td[" + (i % 5 + 1) + "]")).getAttribute("style"));
      System.out.println(color.get(i));
    }
    for (int i = fromPage; i <= toPage; i++) {
      if (expectColor == "White") {
        if (!color.get(i - 1).contains("background-color:")) {
          logger.pass("The page " + i + "'s color is " + expectColor + " as expected.");
        } else {
          logger.error("The page " + i + "'s color is incorrect, expect " + expectColor + " but is " + color.get(i - 1));
          screenShot(driver, "Color_page" + i);
          errorCount++;
        }
      } else {
        if (color.get(i - 1).contains(colorStyle)) {
          logger.pass("The page " + i + "'s color is " + expectColor + " as expected.");
        } else {
          logger.error("The page " + i + "'s color is incorrect, expect " + expectColor + " but is " + color.get(i - 1));
          screenShot(driver, "Color_page" + i);
          errorCount++;
        }
      }
    }
    return errorCount;
  }

}
